package dnl.utils.cp;

import java.io.File;
import java.io.IOException;
import java.io.Reader;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.Map.Entry;
import java.util.Properties;
import java.util.Set;

/**
 * 
 * @author Daniel Orr
 *
 */
public class ClassPathHacker {
	private static final Class<?>[] parameters = new Class[] { URL.class };

	public static void addFile(String s) throws IOException {
		File f = new File(s);
		addFile(f);
	}

	public static void addFile(File f) throws IOException {
		addURL(f.toURI().toURL());
	}

	public static void addURL(URL u) throws IOException {
		URLClassLoader sysloader = (URLClassLoader) ClassLoader.getSystemClassLoader();
		Class<?> sysclass = URLClassLoader.class;

		try {
			Method method = sysclass.getDeclaredMethod("addURL", parameters);
			method.setAccessible(true);
			method.invoke(sysloader, new Object[] { u });
		} catch (Throwable t) {
			t.printStackTrace();
			throw new IOException("Error, could not add URL to system classloader");
		}
	}

	/**
	 * Adds the value of any property that starts with 'class.path.entry' to the
	 * classpath.
	 * 
	 * @param configFile
	 */
	public static void load(Reader reader) {
		Properties properties = new Properties();
		try {
			properties.load(reader);
		} catch (IOException e) {
			e.printStackTrace();
		}
		load(properties);
	}

	/**
	 * Adds the value of any property that starts with 'class.path.entry' to the
	 * classpath.
	 * 
	 * @param properties
	 */
	public static void load(Properties properties) {
		Set<Entry<Object, Object>> entrySet = properties.entrySet();
		for (Entry<Object, Object> entry : entrySet) {
			String val = (String) entry.getValue();
			try {
				String replaceShellVars = ShellEnvironment.replaceShellVariables(val);
				File f = new File(replaceShellVars);
				if(f.exists()){
					ClassPathHacker.addFile(replaceShellVars);
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
}
